﻿using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DllCallMeshAnalysisILSpy
{
    public static class AstNodeExtend
    {
        public static T? FindFistChild<T>(this AstNode @this)
            where T : AstNode
        {
            return FindFistChild(@this, n => n is T) as T;
        }

        public static AstNode? FindFistChild(this AstNode @this, Func<AstNode, bool> func)
        {
            var touchList = new List<AstNode>();
            var searchList = new List<AstNode>(new[] { @this });

            while (true)
            {
                if (searchList?.Any() != true)
                    break;

                var deep = new List<AstNode>(searchList);
                touchList.AddRange(searchList);
                searchList.Clear();

                foreach (var item in deep)
                {
                    if (func(item))
                        return item;

                    if (item.Children?.Any() == true)
                        searchList.AddRange(item.Children.Except(touchList));
                }
            }

            return null;
        }
    }
}
